/** 洛克人系列,主要用于自动蓄力
  基础按键依次为:攻击,跳跃
  
  By setycyas @2025-05-31
*/

/* 全局设定
*/ {
#Warn
#MaxThreadsPerHotkey 1
SetWorkingDir(A_ScriptDir)
#Include "..\Class\FaceDetector.2.ahk"
#Include "..\Class\CommonMacro.2.ahk"
#Include "..\Class\CommonUI.2.ahk"
#Include "..\Class\MyFuns.2.ahk"
#Include "..\Class\MyEmu.2.ahk"
#Include "..\Class\OrderMap.2.ahk"
;SendMode("Event")
SendMode("Input")
}

/* 制作洛克人系列的宏类
*/ class RockmanMacro extends CommonMacro {

  pressDuration := 30
  charging := false ;蓄力标记
  /* 函数
  */
  _chargeChange(value) {
    this.charging	:= value
    if (value) {
      this.UI._statusBar.SetText("自动蓄力中")
    } else {
      this.UI._statusBar.SetText("无自动蓄力")
    }
  }

  /* 新增的宏函数
  */
  ;单发
  _单宏模拟(i, key){
    local vk
    this._down(i)
    vk := GetKeyVK(MyFuns.getHotkey(key))
	  ;sleep(this.autoFireDelay)
    loop {
	    sleep(this.autoFireDelay)
    } until (not MyFuns.getVkState(vk))
    this._up(i)
  }
  _单发A(key){
    this._单宏模拟(1, key)
  }
  _单发B(key){
    this._单宏模拟(2, key)
  }
  ;蓄力
  _蓄力A(key){
    this._down(1)
  }
  _蓄力B(key){
    this._down(2)
  }
  ;轻微位移用
  _右微移(key){
    MyFuns.press("right", 50)
    sleep(50)
  }
  _左微移(key){
    MyFuns.press("left", 50)
    sleep(50)
  }
  _前微移(key){
    MyFuns.press(this._face.face(), 50)
    sleep(50)
  }
  ;滑铲
  _下B(key){
    MyFuns.keyDown("down")
    this._press(2)
    MyFuns.keyUp("down")	  
  }
  ;中等幅度的跳
  _中跳(key){
  	this._down(2)
  	sleep(this.testParams[1])
    this._up(2)	
  }
  ;响应攻击键,绑定在攻击键上刷新蓄力状态
  _响应攻击键(key){
    this._chargeChange(false)
  }
  ;单发A模拟
  _单发A模拟(key){
    if (this.charging){
      this._up(1)
      sleep(30)	
    }
    this._单发A(key)
    this._chargeChange(false)
  }
  ;自动蓄力攻击
  _连发蓄力(key){
    local vk := GetKeyVK(MyFuns.getHotkey(key))
    if (this.charging){
    	this._up(1)
    	this._chargeChange(false)
    	sleep(30)
    } else {
      this._down(1)
      sleep(30)
      this._up(1)	
    }
    if (MyFuns.getVkState(vk)){
      this._down(1)
      this._chargeChange(true)
    }
    while(MyFuns.getVkState(vk)){
      sleep(50)
      this._up(1)
      sleep(50)
      this._down(1)
    }
  }
  
  /* 重载宏接口
  */
  _setMacro(){
    static obm := ObjBindMethod ;函数名简写,制作对象绑定函数
    local m := OrderMap() ;this.macroMap的简写
    ;制作宏相关Map
    this.macroMap := m
    ;通用
    m["左微移"] := obm(this, "_左微移")
    m["右微移"] := obm(this, "_右微移")
    m["前微移"] := obm(this, "_前微移")
    m["中跳"] := obm(this, "_中跳")
    m["连发蓄力"] := obm(this, "_连发蓄力")
    m["响应攻击键"] := obm(this, "_响应攻击键")
    m["下B"] := obm(this, "_下B")
    m["单发A模拟"] :=	obm(this, "_单发A模拟")
    m["空函数"] := obm(this, "_空函数")
    ;制作指定宏顺序的数组
    this.macroArr := m.getKeys()
  }
}

/* 制作洛克人专用UI
*/
class RockmanUI extends CommonUI {

  HOTKEY_NUM := 8
  EXE_ARRAY := ["fceux.exe", MyEmu.FBNEO64, MyEmu.MAME, MyEmu.XZONE]
  
  /* 构造函数
  */
  __New(macro){
    super.__New("洛克人系列", macro)
    this._preset := OrderMap()
    this._macro.UI := this ;绑定UI
    ;预设
    ;this._preset["默认"] := ["响应攻击键", "连发蓄力", "下B", "左微移", "右微移", "单发A模拟", "空函数", "空函数"]
    this._preset["默认"] := ["响应攻击键", "连发蓄力", "下B", "前微移", "中跳", "单发A模拟", "空函数", "空函数"]
  }

  /* 重写接口
  */
  ;自定义gui组件标签页,增加一个挡板召唤键
  _customGui(){
    super._customGui()
  }

  /* 重写setup,更改可选的exe,读入预设
  */
  setup(){
    super.setup()
    this._myGui.opt("+AlwaysOnTop")
    this._myGui.show("x1100 y230")
    this.readPresetMenu("默认")
  }
  
  /* 自定义函数
  */
  
}

/* 运行当前脚本
*/ 
if (A_ScriptName == "洛克人系列.2.ahk") {
  face := FaceDetector() ;方向检测对象
  macro := RockmanMacro(face, ["d","x","r","f", "c", "s"]) ;宏对象,有界面时第二个参数可以随便写但长度不要小于2
  ;新建界面对象并显示
  ui := RockmanUI(macro)
  ui.setup()
  ;更新组件内容
  ui._exeComboBox.Choose("fceux.exe")
  ;ui._exeComboBox.Choose(MyEmu.FBNEO64)
  ;ui._exeComboBox.Choose(MyEmu.XZONE)
  ui._gameKeyEdit.Text := "x,d" ;B攻A跳
  ui._hotkeyEdit.Text := "~x,~s,~f,~w,~e,~a"
  ui._fpsEdit.Text := 15
  ui._testEdit.Text := "50,100,30,30"
  ui.readPresetMenu("默认")
}
